package rn;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import problema.Problema;
import problema.Solucao;

public class TrainningProblem extends Problema {

	private static String IRIS = "./Iris_db/Iris_completo.txt";
	
	public TrainningProblem() {
		super(37, null, null);
		
		valorMaximo = new double[numeroDimensoes];
		valorMinimo = new double[numeroDimensoes];
		for(int i=0; i<numeroDimensoes; i++){
			valorMaximo[i] = 1;
			valorMinimo[i] = -1;
		}
	}
	
	@Override
	public void avaliacaoFitness(Solucao solucao) {
		int[] layersSizes = {4,5,1};
		MLP nn = new MLP(layersSizes, new SigmoidalFunction(), 1);
		
		int cont = 0;
		//Para cada camada, comecando da escondida
		for (int i = 1; i < layersSizes.length; i++) {
			//Para cada neuronio que recebe no qual o valor vai entrar
			for(int j=0; j<layersSizes[i]; j++){
				//Para cada neuronio que o valor veio
				for(int k=0; k<layersSizes[i-1]+1; k++){
					nn.layers[i].neurons[j].inputWeights[k] = solucao.getVariaveis()[cont++]; //recebe do bias
				}
			}
		}
		
		double[][] validationData = readInput(IRIS);
		double[][] validationOutput = readOutput(IRIS);
		
		double error = nn.validateNetwork(validationData, validationOutput, 0, 1);
		solucao.setFitness(error);
	}

	@Override
	public void avaliacaoFitness(List<Solucao> solucoes) {
		for (Solucao sol : solucoes) {
			avaliacaoFitness(sol);
		}
		
	}

	private static double[][] readInput(String path){
		double[][] retorno = null;
		try {
			ArrayList<double[]> listaTemp = new ArrayList<>();
			File file = new File(path);
			Scanner reader = new Scanner(file);

			while(reader.hasNextLine()){
				String[] line = reader.nextLine().split("\t");
				double[] values = new double[4]; 

				values[0] = Double.parseDouble(line[0]);
				values[1] = Double.parseDouble(line[1]);
				values[2] = Double.parseDouble(line[2]);
				values[3] = Double.parseDouble(line[3]);

				listaTemp.add(values);
			}

			retorno = new double[listaTemp.size()][4];

			for(int i=0; i<retorno.length; i++){
				retorno[i] = listaTemp.get(i);
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

		return retorno;
	}

	private static double[][] readOutput(String path){
		double[][] retorno = null;
		try {
			ArrayList<double[]> listaTemp = new ArrayList<>();
			File file = new File(path);
			Scanner reader = new Scanner(file);

			while(reader.hasNextLine()){
				String[] line = reader.nextLine().split("\t");
				double[] values = new double[1]; 

				values[0] = Double.parseDouble(line[4]);

				listaTemp.add(values);
			}

			retorno = new double[listaTemp.size()][1];

			for(int i=0; i<retorno.length; i++){
				retorno[i] = listaTemp.get(i);
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

		return retorno;
	}
	
}
